package edu.northwestern.cbits.purple_robot_manager.models.trees.parsers; import java.util.ArrayList; import java.util.HashMap; import edu.northwestern.cbits.purple_robot_manager.models.trees.BranchNode; import edu.northwestern.cbits.purple_robot_manager.models.trees.LeafNode; import edu.northwestern.cbits.purple_robot_manager.models.trees.TreeNode; import edu.northwestern.cbits.purple_robot_manager.models.trees.TreeNode.TreeNodeException; public class MatLabBinaryTreeParser extends TreeNodeParser { private ArrayList<String> _lines = new ArrayList<>(); @Override public TreeNode parse(String content) throws TreeNodeException { String[] lines = content.split("\\r?\\n"); // Add an empty line so that line number = index = node ID. this._lines.add(""); for (String line : lines) this._lines.add(line.trim()); return this.treeForNode(1, ""); } private TreeNode treeForNode(int lineNo, String prefix) throws TreeNodeException { String line = this._lines.get(lineNo); String[] leaf = line.split(" class = "); if (leaf.length == 2) { // leaf[1] = prediction, using "1.0" since no accuracy is available. HashMap<String, Object> prediction = new HashMap<>(); prediction.put(LeafNode.ACCURACY, 1.0); prediction.put(LeafNode.PREDICTION, leaf[1]); return new LeafNode(prefix + "->" + lineNo, prediction); } else { BranchNode branch = new BranchNode(prefix + "->" + lineNo); // split the non-leaf line into the two conditions String[] branchLines = line.substring(6).split(" else"); String ifString = branchLines[0]; String elseString = branchLines[1]; // At this point, we have 2 strings that look like: // "if x10<-0.999999 then node 4" ifString = ifString.replace("if ", ""); ifString = ifString.replace("<", "|"); ifString = ifString.replace(" then node ", "|"); // After the above, we should have something like // "x10|-0.999999|4" elseString = elseString.replace("if ", ""); elseString = elseString.replace(">=", "|"); elseString = elseString.replace(" then node ", "|"); String[] ifTokens = ifString.split("\\|"); String[] elseTokens = elseString.split("\\|"); // Turn into conditions & next nodes... String nextIfId = ifTokens[2]; // Create a tree node for the destination node. TreeNode nextIfNode = this.treeForNode(Integer.parseInt(nextIfId), prefix + "->" + lineNo); // Get the test line components. BranchNode.Operation op = BranchNode.Operation.LESS_THAN; String feature = ifTokens[0]; Double value = Double.valueOf(ifTokens[1]); branch.addCondition(op, feature.trim(), value, BranchNode.Condition.DEFAULT_PRIORITY, nextIfNode); // Create a tree node for the destination node. String nextElseId = elseTokens[2]; TreeNode nextElseNode = this.treeForNode(Integer.parseInt(nextElseId), prefix + "->" + lineNo); // Get the test line components. BranchNode.Operation elseOp = BranchNode.Operation.MORE_THAN_OR_EQUAL_TO; feature = elseTokens[0]; value = Double.valueOf(elseTokens[1]); branch.addCondition(elseOp, feature.trim(), value, BranchNode.Condition.LOWEST_PRIORITY, nextElseNode); return branch; } } }